home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -serious- / graphics / gnuplot / gnuplot-3.7.1src / gnuplot-3.7.1 / plot.c < prev    next >
C/C++ Source or Header  |  1999-11-29  |  18KB  |  727 lines

  1. #ifndef lintuse free() insteSid = "$Id: plot.c,v 1.18.2.2 1999/09/23 13:26:36 lhecking Exp $";
  2. #endif
  3.  
  4. /* GNUPLOT - plot.c */
  5.  
  6. /*[
  7.  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
  8.  *
  9.  * Permission to use, copy, and distribute this software and its
  10.  * documentation for any purpose with or without fee is hereby granted,
  11.  * provided that the above copyright notice appear in all copies and
  12.  * that both that copyright notice and this permission notice appear
  13.  * in supporting documentation.
  14.  *
  15.  * Permission to modify the software is granted, but not the right to
  16.  * distribute the complete modified source code.  Modifications are to
  17.  * be distributed as patches to the released version.  Permission to
  18.  * distribute binaries produced by compiling modified sources is granted,
  19.  * provided you
  20.  *   1. distribute the corresponding source modifications from the
  21.  *    released version in the form of a patch file along with the binaries,
  22.  *   2. add special version identification to distinguish your version
  23.  *    in addition to the base release version number,
  24.  *   3. provide your name and address as the primary contact for the
  25.  *    support of your modified version, and
  26.  *   4. retain our contact information in regard to use of the base
  27.  *    software.
  28.  * Permission to distribute the released version of the source code along
  29.  * with corresponding source modifications in the form of a patch file is
  30.  * granted with same provisions 2 through 4 for binary distributions.
  31.  *
  32.  * This software is provided "as is" without express or implied warranty
  33.  * to the extent permitted by applicable law.
  34. ]*/
  35.  
  36. #include <signal.h>
  37.  
  38. #include "plot.h"
  39. #include "fit.h"
  40. #include "setshow.h"
  41. #include "fnproto.h"
  42. #include <setjmp.h>
  43.  
  44. #if defined(MSDOS) || defined(DOS386) || defined(__EMX__)
  45. # include <io.h>
  46. #endif
  47.  
  48. /* HBB: for the control87 function, if used with DJGPP V1: */
  49. #if defined(DJGPP) && (DJGPP!=2)
  50. # include "ctrl87.h"
  51. #endif
  52.  
  53. #ifdef VMS
  54. # ifndef __GNUC__
  55. #  include <unixio.h>
  56. # endif
  57. # include <smgdef.h>
  58. extern int vms_vkid;
  59. extern smg$create_virtual_keyboard();
  60. extern int vms_ktid;
  61. extern smg$create_key_table();
  62. #endif /* VMS */
  63.  
  64. #ifdef AMIGA_SC_6_1
  65. # include <proto/dos.h>
  66. #endif
  67.  
  68. #ifdef _Windows
  69. # include <windows.h>
  70. # ifndef SIGINT
  71. #  define SIGINT 2        /* for MSC */
  72. # endif
  73. #endif /* _Windows */
  74.  
  75. extern FILE *gpoutfile;
  76.  
  77. TBOOLEAN interactive = TRUE;    /* FALSE if stdin not a terminal */
  78. TBOOLEAN noinputfiles = TRUE;    /* FALSE if there are script files */
  79.  
  80. /*  these 2 could be in misc.c, but are here with all the other globals */
  81. TBOOLEAN do_load_arg_substitution = FALSE;
  82. char *call_args[10] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  83.  
  84. char *infile_name = NULL;    /* name of command file; NULL if terminal */
  85.  
  86. #ifdef HAVE_LIBREADLINE
  87. extern char *rl_readline_name;
  88. extern int rl_complete_with_tilde_expansion;
  89. #endif
  90.  
  91. #ifdef X11
  92. extern int X11_args __PROTO((int, char **));
  93. #endif
  94.  
  95. /* patch to get home dir, see command.c */
  96. #if (defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))) || defined(DJGPP)
  97. # include <dir.h>        /* MAXPATH */
  98. char HelpFile[MAXPATH];
  99. #endif /*   - DJL */
  100.  
  101. #ifndef STDOUT
  102. # define STDOUT 1
  103. #endif
  104.  
  105. /* a longjmp buffer to get back to the command line */
  106. #ifdef _Windows
  107. static jmp_buf far command_line_env;
  108. #else
  109. static jmp_buf command_line_env;
  110. #endif
  111.  
  112. static void load_rcfile __PROTO((void));
  113. RETSIGTYPE inter __PROTO((int anint));
  114.  
  115. /* built-in function table */
  116. struct ft_entry GPFAR ft[] =
  117. {
  118.     /* internal functions: */
  119.     {"push", (FUNC_PTR) f_push},
  120.     {"pushc", (FUNC_PTR) f_pushc},
  121.     {"pushd1", (FUNC_PTR) f_pushd1},
  122.     {"pushd2", (FUNC_PTR) f_pushd2},
  123.     {"pushd", (FUNC_PTR) f_pushd},
  124.     {"call", (FUNC_PTR) f_call},
  125.     {"calln", (FUNC_PTR) f_calln},
  126.     {"lnot", (FUNC_PTR) f_lnot},
  127.     {"bnot", (FUNC_PTR) f_bnot},
  128.     {"uminus", (FUNC_PTR) f_uminus},
  129.     {"lor", (FUNC_PTR) f_lor},
  130.     {"land", (FUNC_PTR) f_land},
  131.     {"bor", (FUNC_PTR) f_bor},
  132.     {"xor", (FUNC_PTR) f_xor},
  133.     {"band", (FUNC_PTR) f_band},
  134.     {"eq", (FUNC_PTR) f_eq},
  135.     {"ne", (FUNC_PTR) f_ne},
  136.     {"gt", (FUNC_PTR) f_gt},
  137.     {"lt", (FUNC_PTR) f_lt},
  138.     {"ge", (FUNC_PTR) f_ge},
  139.     {"le", (FUNC_PTR) f_le},
  140.     {"plus", (FUNC_PTR) f_plus},
  141.     {"minus", (FUNC_PTR) f_minus},
  142.     {"mult", (FUNC_PTR) f_mult},
  143.     {"div", (FUNC_PTR) f_div},
  144.     {"mod", (FUNC_PTR) f_mod},
  145.     {"power", (FUNC_PTR) f_power},
  146.     {"factorial", (FUNC_PTR) f_factorial},
  147.     {"bool", (FUNC_PTR) f_bool},
  148.     {"dollars", (FUNC_PTR) f_dollars},    /* for using extension */
  149.     {"jump", (FUNC_PTR) f_jump},
  150.     {"jumpz", (FUNC_PTR) f_jumpz},
  151.     {"jumpnz", (FUNC_PTR) f_jumpnz},
  152.     {"jtern", (FUNC_PTR) f_jtern},
  153.  
  154. /* standard functions: */
  155.     {"real", (FUNC_PTR) f_real},
  156.     {"imag", (FUNC_PTR) f_imag},
  157.     {"arg", (FUNC_PTR) f_arg},
  158.     {"conjg", (FUNC_PTR) f_conjg},
  159.     {"sin", (FUNC_PTR) f_sin},
  160.     {"cos", (FUNC_PTR) f_cos},
  161.     {"tan", (FUNC_PTR) f_tan},
  162.     {"asin", (FUNC_PTR) f_asin},
  163.     {"acos", (FUNC_PTR) f_acos},
  164.     {"atan", (FUNC_PTR) f_atan},
  165.     {"atan2", (FUNC_PTR) f_atan2},
  166.     {"sinh", (FUNC_PTR) f_sinh},
  167.     {"cosh", (FUNC_PTR) f_cosh},
  168.     {"tanh", (FUNC_PTR) f_tanh},
  169.     {"int", (FUNC_PTR) f_int},
  170.     {"abs", (FUNC_PTR) f_abs},
  171.     {"sgn", (FUNC_PTR) f_sgn},
  172.     {"sqrt", (FUNC_PTR) f_sqrt},
  173.     {"exp", (FUNC_PTR) f_exp},
  174.     {"log10", (FUNC_PTR) f_log10},
  175.     {"log", (FUNC_PTR) f_log},
  176.     {"besj0", (FUNC_PTR) f_besj0},
  177.     {"besj1", (FUNC_PTR) f_besj1},
  178.     {"besy0", (FUNC_PTR) f_besy0},
  179.     {"besy1", (FUNC_PTR) f_besy1},
  180.     {"erf", (FUNC_PTR) f_erf},
  181.     {"erfc", (FUNC_PTR) f_erfc},
  182.     {"gamma", (FUNC_PTR) f_gamma},
  183.     {"lgamma", (FUNC_PTR) f_lgamma},
  184.     {"ibeta", (FUNC_PTR) f_ibeta},
  185.     {"igamma", (FUNC_PTR) f_igamma},
  186.     {"rand", (FUNC_PTR) f_rand},
  187.     {"floor", (FUNC_PTR) f_floor},
  188.     {"ceil", (FUNC_PTR) f_ceil},
  189.  
  190.     {"norm", (FUNC_PTR) f_normal},    /* XXX-JG */
  191.     {"inverf", (FUNC_PTR) f_inverse_erf},    /* XXX-JG */
  192.     {"invnorm", (FUNC_PTR) f_inverse_normal},    /* XXX-JG */
  193.     {"asinh", (FUNC_PTR) f_asinh},
  194.     {"acosh", (FUNC_PTR) f_acosh},
  195.     {"atanh", (FUNC_PTR) f_atanh},
  196.  
  197.     {"column", (FUNC_PTR) f_column},    /* for using */
  198.     {"valid", (FUNC_PTR) f_valid},    /* for using */
  199.     {"timecolumn", (FUNC_PTR) f_timecolumn},    /* for using */
  200.  
  201.     {"tm_sec", (FUNC_PTR) f_tmsec},    /* for timeseries */
  202.     {"tm_min", (FUNC_PTR) f_tmmin},    /* for timeseries */
  203.     {"tm_hour", (FUNC_PTR) f_tmhour},    /* for timeseries */
  204.     {"tm_mday", (FUNC_PTR) f_tmmday},    /* for timeseries */
  205.     {"tm_mon", (FUNC_PTR) f_tmmon},    /* for timeseries */
  206.     {"tm_year", (FUNC_PTR) f_tmyear},    /* for timeseries */
  207.     {"tm_wday", (FUNC_PTR) f_tmwday},    /* for timeseries */
  208.     {"tm_yday", (FUNC_PTR) f_tmyday},    /* for timeseries */
  209.  
  210.     {NULL, NULL}
  211. };
  212.  
  213. static struct udvt_entry udv_pi = { NULL, "pi", FALSE };
  214. /* first in linked list */
  215. struct udvt_entry *first_udv = &udv_pi;
  216. struct udft_entry *first_udf = NULL;
  217.  
  218. static int exit_status = EXIT_SUCCESS;
  219.  
  220. #ifdef OS2
  221. # define INCL_DOS
  222. # define INCL_REXXSAA
  223. # include <os2.h>
  224. # include <process.h>
  225. ULONG RexxInterface(PRXSTRING, PUSHORT, PRXSTRING);
  226. int ExecuteMacro(char *, int);
  227. void PM_intc_cleanup();
  228. void PM_setup();
  229. #endif /* OS2 */
  230.  
  231. #if defined(ATARI) || defined(MTOS)
  232. /* For findfile () (?) */
  233. # include <support.h>
  234. void appl_exit(void);
  235. void MTOS_open_pipe(void);
  236. extern int aesid;
  237. #endif
  238.  
  239. RETSIGTYPE inter(anint)
  240. int anint;
  241. {
  242. #ifdef OS2
  243.     (void) signal(anint, SIG_ACK);
  244. #else
  245.     (void) signal(SIGINT, (sigfunc) inter);
  246. #endif
  247.  
  248. #ifndef DOSX286
  249.     (void) signal(SIGFPE, SIG_DFL);    /* turn off FPE trapping */
  250. #endif
  251. #ifdef OS2
  252.     PM_intc_cleanup();
  253. #else
  254.     term_reset();
  255.     (void) putc('\n', stderr);
  256.     longjmp(command_line_env, TRUE);    /* return to prompt */
  257. #endif
  258. }
  259.  
  260. #ifdef LINUXVGA
  261. /* utility functions to ensure that setuid gnuplot
  262.  * assumes root privileges only for those parts
  263.  * of the code which require root rights.
  264.  *
  265.  * By "Dr. Werner Fink" <werner@suse.de>
  266.  */
  267. static uid_t euid, ruid;
  268. static gid_t egid, rgid;
  269. static int asked_privi = 0;
  270.  
  271. void
  272. drop_privilege()
  273. {
  274.     if (!asked_privi) {
  275.     euid = geteuid();
  276.     egid = getegid();
  277.     ruid = getuid();
  278.     rgid = getgid();
  279.     asked_privi = 1;
  280.     }
  281.     if (setegid(rgid) == -1)
  282.     (void) fprintf(stderr, "setegid(%d): %s\n",
  283.                (int) rgid, strerror(errno));
  284.     if (seteuid(ruid) == -1)
  285.     (void) fprintf(stderr, "seteuid(%d): %s\n",
  286.                (int) ruid, strerror(errno));
  287. }
  288.  
  289. void
  290. take_privilege()
  291. {
  292.     if (!asked_privi) {
  293.     euid = geteuid();
  294.     egid = getegid();
  295.     ruid = getuid();
  296.     rgid = getgid();
  297.     asked_privi = 1;
  298.     }
  299.     if (setegid(egid) == -1)
  300.     (void) fprintf(stderr, "setegid(%d): %s\n",
  301.                (int) egid, strerror(errno));
  302.     if (seteuid(euid) == -1)
  303.     (void) fprintf(stderr, "seteuid(%d): %s\n",
  304.                (int) euid, strerror(errno));
  305. }
  306. #endif /* LINUXVGA */
  307.  
  308.  
  309. /* a wrapper for longjmp so we can keep everything local */
  310. void bail_to_command_line()
  311. {
  312.     longjmp(command_line_env, TRUE);
  313. }
  314.  
  315. #if defined(_Windows) || defined(_Macintosh)
  316. int gnu_main(argc, argv)
  317. #else
  318. int main(argc, argv)
  319. #endif
  320. int argc;
  321. char **argv;
  322. {
  323. #ifdef LINUXVGA
  324.     LINUX_setup();
  325. #endif
  326. /* make sure that we really have revoked root access, this might happen if
  327.    gnuplot is compiled without vga support but is installed suid by mistake */
  328. #ifdef __linux__
  329.     setuid(getuid());
  330. #endif
  331. #if defined(MSDOS) && !defined(_Windows) && !defined(__GNUC__)
  332.     PC_setup();
  333. #endif /* MSDOS !Windows */
  334. /* HBB: Seems this isn't needed any more for DJGPP V2? */
  335. /* HBB: disable all floating point exceptions, just keep running... */
  336. #if defined(DJGPP) && (DJGPP!=2)
  337.     _control87(MCW_EM, MCW_EM);
  338. #endif
  339.  
  340. #if defined(OS2)
  341.     int rc;
  342.     if (_osmode == OS2_MODE) {
  343.     PM_setup();
  344.     rc = RexxRegisterSubcomExe("GNUPLOT", (PFN) RexxInterface, NULL);
  345.     }
  346. #endif
  347.  
  348. /* malloc large blocks, otherwise problems with fragmented mem */
  349. #ifdef OSK
  350.     _mallocmin(102400);
  351. #endif
  352.  
  353. #ifdef MALLOCDEBUG
  354.     malloc_debug(7);
  355. #endif
  356.  
  357. /* get helpfile from home directory */
  358. #ifndef DOSX286
  359. # ifndef _Windows
  360. #  if defined (__TURBOC__) && (defined (MSDOS) || defined(DOS386))
  361.     strcpy(HelpFile, argv[0]);
  362.     strcpy(strrchr(HelpFile, DIRSEP1), "\\gnuplot.gih");
  363. #  endif            /*   - DJL */
  364. # endif                /* !_Windows */
  365. #endif /* !DOSX286 */
  366. #ifdef __DJGPP__
  367.     {
  368.     char *s;
  369.     strcpy(HelpFile, argv[0]);
  370.     for (s = HelpFile; *s; s++)
  371.         if (*s == DIRSEP1)
  372.         *s = DIRSEP2;    /* '\\' to '/' */
  373.     strcpy(strrchr(HelpFile, DIRSEP2), "/gnuplot.gih");
  374.     }        /* Add also some "paranoid" tests for '\\':  AP */
  375. #endif /* DJGPP */
  376.  
  377. #ifdef VMS
  378.     unsigned int status[2] = { 1, 0 };
  379. #endif
  380.  
  381. #ifdef HAVE_LIBREADLINE
  382.     rl_readline_name = argv[0];
  383.     rl_complete_with_tilde_expansion = 1;
  384. #endif
  385.  
  386. #ifdef X11
  387.     {
  388.     int n = X11_args(argc, argv);
  389.     argv += n;
  390.     argc -= n;
  391.     }
  392. #endif
  393.  
  394. #ifdef apollo
  395.     apollo_pfm_catch();
  396. #endif
  397.  
  398. /* moved to ATARI_init in atariaes.trm */
  399. /* #ifdef ATARI
  400.    void application_init(void);
  401.    application_init();
  402.    #endif */
  403.  
  404. #ifdef MTOS
  405.     MTOS_open_pipe();
  406. #endif
  407.  
  408.     setbuf(stderr, (char *) NULL);
  409.  
  410. #ifndef NO_SETVBUF
  411.     /* this was once setlinebuf(). Docs say this is
  412.      * identical to setvbuf(,NULL,_IOLBF,0), but MS C
  413.      * faults this (size out of range), so we try with
  414.      * size of 1024 instead. [SAS/C does that, too. -lh]
  415.      * Failing this, I propose we just make the call and
  416.      * ignore the return : its probably not a big deal
  417.      */
  418.     if (setvbuf(stdout, (char *) NULL, _IOLBF, (size_t) 1024) != 0)
  419.     fputs("Could not linebuffer stdout\n", stderr);
  420. #endif
  421.  
  422.     gpoutfile = stdout;
  423.     (void) Gcomplex(&udv_pi.udv_value, Pi, 0.0);
  424.  
  425.     init_memory();
  426.  
  427.     interactive = FALSE;
  428.     init_terminal();        /* can set term type if it likes */
  429.  
  430. #ifdef AMIGA_SC_6_1
  431.     if (IsInteractive(Input()) == DOSTRUE)
  432.     interactive = TRUE;
  433.     else
  434.     interactive = FALSE;
  435. #else
  436. # if (defined(__MSC__) && defined(_Windows)) || defined(__WIN32__)
  437.     interactive = TRUE;
  438. # else
  439.     interactive = isatty(fileno(stdin));
  440. # endif
  441. #endif /* !AMIGA_SC_6_1 */
  442.  
  443.     if (argc > 1)
  444.     interactive = noinputfiles = FALSE;
  445.     else
  446.     noinputfiles = TRUE;
  447.  
  448.     if (interactive)
  449.     show_version(stderr);
  450.  
  451. #ifdef VMS
  452.     /* initialise screen management routines for command recall */
  453.     if (status[1] = smg$create_virtual_keyboard(&vms_vkid) != SS$_NORMAL)
  454.     done(status[1]);
  455.     if (status[1] = smg$create_key_table(&vms_ktid) != SS$_NORMAL)
  456.     done(status[1]);
  457. #endif /* VMS */
  458.  
  459.     if (!setjmp(command_line_env)) {
  460.     /* first time */
  461.     interrupt_setup();
  462.     load_rcfile();
  463.     init_fit();        /* Initialization of fitting module */
  464.  
  465.     if (interactive && term != 0)    /* not unknown */
  466.         fprintf(stderr, "\nTerminal type set to '%s'\n", term->name);
  467.     } else {
  468.     /* come back here from int_error() */
  469.     if (interactive == FALSE)
  470.         exit_status = EXIT_FAILURE;
  471.  
  472. #ifdef AMIGA_SC_6_1
  473.     (void) rawcon(0);
  474. #endif
  475.     load_file_error();    /* if we were in load_file(), cleanup */
  476. #ifdef _Windows
  477.     SetCursor(LoadCursor((HINSTANCE) NULL, IDC_ARROW));
  478. #endif
  479.  
  480. #ifdef VMS
  481.     /* after catching interrupt */
  482.     /* VAX stuffs up stdout on SIGINT while writing to stdout,
  483.        so reopen stdout. */
  484.     if (gpoutfile == stdout) {
  485.         if ((stdout = freopen("SYS$OUTPUT", "w", stdout)) == NULL) {
  486.         /* couldn't reopen it so try opening it instead */
  487.         if ((stdout = fopen("SYS$OUTPUT", "w")) == NULL) {
  488.             /* don't use int_error here - causes infinite loop! */
  489.             fputs("Error opening SYS$OUTPUT as stdout\n", stderr);
  490.         }
  491.         }
  492.         gpoutfile = stdout;
  493.     }
  494. #endif /* VMS */
  495.     if (!interactive && !noinputfiles) {
  496.         term_reset();
  497. #if defined(ATARI) || defined(MTOS)
  498.         if (aesid > -1)
  499.         atexit(appl_exit);
  500. #endif
  501.         return (IO_ERROR);    /* exit on non-interactive error */
  502.     }
  503.     }
  504.  
  505.     if (argc > 1) {
  506. #ifdef _Windows
  507.     int noend = 0;
  508. #endif
  509.  
  510.     /* load filenames given as arguments */
  511.     while (--argc > 0) {
  512.         ++argv;
  513.         c_token = NO_CARET;    /* in case of file not found */
  514. #ifdef _Windows
  515.         if (stricmp(*argv, "-noend") == 0 || stricmp(*argv, "/noend") == 0)
  516.         noend = 1;
  517.         else
  518. #endif
  519.         if (strcmp(*argv, "-") == 0) {
  520.         /* DBT 10-7-98  go interactive if "-" on command line */
  521.  
  522.         interactive = TRUE;
  523.         /* will this work on all platforms? */
  524.  
  525.         while (!com_line());
  526.  
  527.         /* interactive = FALSE; */ /* should this be here? */
  528.  
  529.         } else
  530.         load_file(fopen(*argv, "r"), *argv, FALSE);
  531.     }
  532. #ifdef _Windows
  533.     if (noend) {
  534.         interactive = TRUE;
  535.         while (!com_line());
  536.     }
  537. #endif
  538.     } else {
  539.     /* take commands from stdin */
  540.     while (!com_line());
  541.     }
  542.  
  543.     term_reset();
  544.  
  545. #ifdef OS2
  546.     if (_osmode == OS2_MODE)
  547.     RexxDeregisterSubcom("GNUPLOT", NULL);
  548. #endif
  549.  
  550. #if defined(ATARI) || defined(MTOS)
  551.     if (aesid > -1)
  552.     atexit(appl_exit);
  553. #endif
  554.     return (exit_status);
  555. }
  556.  
  557. #if (defined(ATARI) || defined(MTOS)) && defined(__PUREC__)
  558. int purec_matherr(struct exception *e)
  559. {
  560.     char *c;
  561.     switch (e->type) {
  562.     case DOMAIN:
  563.     c = "domain error";
  564.     break;
  565.     case SING:
  566.     c = "argument singularity";
  567.     break;
  568.     case OVERFLOW:
  569.     c = "overflow range";
  570.     break;
  571.     case UNDERFLOW:
  572.     c = "underflow range";
  573.     break;
  574.     default:
  575.     c = "(unknown error";
  576.     break;
  577.     }
  578.     fprintf(stderr, "\
  579. math exception : %s\n\
  580.     name : %s\n\
  581.     arg 1: %e\n\
  582.     arg 2: %e\n\
  583.     ret  : %e\n",
  584.         c,
  585.         e->name,
  586.         e->arg1,
  587.         e->arg2,
  588.         e->retval);
  589.  
  590.     return 1;
  591. }
  592. #endif /* (ATARI || MTOS) && PUREC */
  593.  
  594.  
  595. /* Set up to catch interrupts */
  596. void interrupt_setup()
  597. {
  598. #ifdef __PUREC__
  599.     setmatherr(purec_matherr);
  600. #endif
  601.  
  602.     (void) signal(SIGINT, (sigfunc) inter);
  603.  
  604. #ifdef SIGPIPE
  605.     /* ignore pipe errors, this might happen with set output "|head" */
  606.     (void) signal(SIGPIPE, SIG_IGN);
  607. #endif /* SIGPIPE */
  608. }
  609.  
  610.  
  611. /* Look for a gnuplot init file in . or home directory */
  612. static void load_rcfile()
  613. {
  614.     FILE *plotrc = NULL;
  615.     char home[80];
  616.     char rcfile[sizeof(PLOTRC) + 80];
  617.     char *tmp_home = NULL;
  618. #ifndef VMS
  619.     char *p;    /* points to last char in home path, or to \0, if none */
  620.  
  621.     tmp_home = getenv(HOME);
  622.     if (tmp_home) {
  623.     safe_strncpy(home, tmp_home, sizeof(home));
  624.     if (strlen(home))
  625.         p = &home[strlen(home) - 1];
  626.     else
  627.         p = home;
  628.     if ((*p != DIRSEP1) && (*p != DIRSEP2) && (*p != NUL)) {
  629.         assert(p >= home && p <= (home + sizeof(home) - 1 - 2));
  630.         if (*p)
  631.         p++;
  632.         *p++ = DIRSEP1;
  633.         *p = NUL;
  634.     }
  635.     }
  636. #else /* VMS */
  637.     safe_strncpy(home, HOME, sizeof(home));
  638.     tmp_home = home;
  639. #endif /* VMS */
  640.  
  641. #ifdef NOCWDRC
  642.     /* inhibit check of init file in current directory for security reasons */
  643. #else
  644.     (void) strcpy(rcfile, PLOTRC);
  645.     plotrc = fopen(rcfile, "r");
  646. #endif /* !NOCWDRC */
  647.  
  648.     if (plotrc == NULL) {
  649.     if (tmp_home) {
  650.         (void) sprintf(rcfile, "%s%s", home, PLOTRC);
  651.         plotrc = fopen(rcfile, "r");
  652. #if defined(ATARI) || defined(MTOS)
  653.         if (plotrc == NULL) {
  654.         char const *const ext[] = { NULL };
  655.         char *ini_ptr = findfile(PLOTRC, getenv("GNUPLOTPATH"), ext);
  656.  
  657.         if (ini_ptr)
  658.             plotrc = fopen(ini_ptr, "r");
  659.         }
  660. #endif /* ATARI || MTOS */
  661.     }
  662.     }
  663.     if (plotrc)
  664.     load_file(plotrc, rcfile, FALSE);
  665. }
  666.  
  667. #ifdef OS2
  668.  
  669. int ExecuteMacro(char *argv, int namelength)
  670. {
  671.     RXSTRING rxRc;
  672.     RXSTRING rxArg;
  673.     char pszName[CCHMAXPATH];
  674.     short sRc;
  675.     int rc;
  676.  
  677.     safe_strncpy(pszName, argv, sizeof(pszName));
  678.     MAKERXSTRING(rxArg, argv, strlen(argv));
  679.     rc = RexxStart(1,
  680.            &rxArg,
  681.            pszName,
  682.            NULL,
  683.            "GNUPLOT",
  684.            RXCOMMAND,
  685.            NULL,
  686.            &sRc,
  687.            &rxRc);
  688.     if (rc == -4)
  689.     rc = 0;            /* run was cancelled-don't give error message */
  690.  
  691. /* We don't use this value ?
  692.    BTW, don't use free() instead since it's allocated inside RexxStart() */
  693.     DosFreeMem(rxRc.strptr);
  694.     return rc;
  695. }
  696.  
  697. ULONG RexxInterface(PRXSTRING rxCmd, PUSHORT pusErr, PRXSTRING rxRc)
  698. /*
  699.    ** Rexx command line interface
  700.  */
  701. {
  702.     int rc;
  703.     static jmp_buf keepenv;
  704.     int cmdlen;
  705.  
  706.     memcpy(keepenv, command_line_env, sizeof(jmp_buf));
  707.     if (!setjmp(command_line_env)) {
  708.     /* set variable input_line.
  709.      * Watch out for line length of NOT_ZERO_TERMINATED strings ! */
  710.     cmdlen = rxCmd->strlength + 1;
  711.     safe_strncpy(input_line, rxCmd->strptr, cmdlen);
  712.     input_line[cmdlen] = NUL;
  713.  
  714.     rc = do_line();
  715.     *pusErr = RXSUBCOM_OK;
  716.     rxRc->strptr[0] = rc + '0';
  717.     rxRc->strptr[1] = NUL;
  718.     rxRc->strlength = strlen(rxRc->strptr);
  719.     } else {
  720.     *pusErr = RXSUBCOM_ERROR;
  721.     RexxSetHalt(getpid(), 1);
  722.     }
  723.     memcpy(command_line_env, keepenv, sizeof(jmp_buf));
  724.     return 0;
  725. }
  726. #endif
  727.